/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package controler;

import algorithm.Dijkstra;
import graph.DijkstraResult;
import graph.DijkstraResultComparatorByDist;
import graph.Graph;
import graph.Node;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;
import javax.naming.spi.DirStateFactory.Result;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JOptionPane;
import models.ResultTableModel;
import view.ResultWindow;
import view.SimulationWindow;

/**
 *
 * @author borysfan
 */
public class SimulationControler {
    private SimulationWindow window;
    private Controler controler;

    public SimulationControler(Controler c){
        window = new SimulationWindow();
        controler = c;
        initActions();
        window.setVisible(true);
        setBeginNames();
        setEndNames();
        setCriteria();
    }

    public SimulationWindow getView(){
        return window;
    }

    private void initActions(){
        window.addCloseAction(new CloseSimulation());
        window.addStartAction(new StartSimulation());
        window.addStepByStepAction(new StepByStepAction());
    }

    public void setBeginNames(){
        Graph grahp = Graph.getInstance();
        ArrayList<String> edgeNames = grahp.getEdgesNames();
        String [] names = new String[edgeNames.size()];
        for(int i=0;i<edgeNames.size();i++){
            names[i]=edgeNames.get(i);
        }
        DefaultComboBoxModel model = new DefaultComboBoxModel(names);
        window.setStartComboBoxModel(model);
    }

    public void setEndNames(){
        Graph grahp = Graph.getInstance();
        ArrayList<String> edgeNames = grahp.getEdgesNames();
        String [] names = new String[edgeNames.size()];
        for(int i=0;i<edgeNames.size();i++){
            names[i]=edgeNames.get(i);
        }
        DefaultComboBoxModel model = new DefaultComboBoxModel(names);
        window.setEndComboBoxModel(model);
    }

    public void setCriteria(){
        String [] criteriaNames = {"najkrótsza droga","najkrótszy czas"};
        DefaultComboBoxModel model = new DefaultComboBoxModel(criteriaNames);
        window.setCriteriaComboBoxModel(model);
    }

    private Node getSelectedStart(){
        String start = window.getSelectedStart();
        Graph g = Graph.getInstance();
        return g.findNodeByName(start);
    }

    private Node getSelectedEnd(){
        String end = window.getSelectedEnd();
        Graph g = Graph.getInstance();
        return g.findNodeByName(end);
    }


    ////////////////////ActionListenery

    private class CloseSimulation implements ActionListener{

        public void actionPerformed(ActionEvent e) {
            window.dispose();
        }

    }

    private class StartSimulation implements ActionListener{

        public void actionPerformed(ActionEvent e) {
            
            ResultTableModel tableModel = new ResultTableModel();
            Node start = getSelectedStart();
            Node end = getSelectedEnd();
            System.out.println("Start: "+start.getName()+" Koniec: "+end.getName());
            boolean weatherCond = isCheckedWeather();
            boolean roadCond = isCheckedRoad();
            boolean trafficCond = isCheckedTraffic();
            if(start!=null && end!=null){
                if(start.equals(end)){
                    JOptionPane.showMessageDialog(window, "Punky początkowy i końcowy muszą być różne!");
                    return;
                }


                int criteria = window.getSelectedItemIndex();
                System.out.println(criteria);
                System.out.println("Szukam drogi...");
                Graph g = Graph.getInstance();
                Dijkstra dijkstra = new Dijkstra();
                ArrayList<DijkstraResult> resultDijkstra = null;
                switch(criteria){
                    case 0:
                            //dijkstra.computeByDistance(start,weatherCond,roadCond,trafficCond);
                            resultDijkstra = dijkstra.getAllPaths(start, end, weatherCond, roadCond, trafficCond);
                            break;

                    case 1: //dijkstra.computeByTime(start,weatherCond,roadCond,trafficCond);
                            resultDijkstra = dijkstra.getAllPathsByTime(start, end, weatherCond, roadCond, trafficCond);
                            break;

                    case 2: //dijkstra.computeBySpeed(start,weatherCond,roadCond,trafficCond);
                             resultDijkstra = dijkstra.getAllPathsBySpeed(start, end, weatherCond, roadCond, trafficCond);
                            break;
                   
                }

                Arrays.sort(resultDijkstra.toArray(),new DijkstraResultComparatorByDist());
                for(int i=0;i<resultDijkstra.size();i++){
                    tableModel.addResult(resultDijkstra.get(i));
                }

            }
            window.dispose();
            
            ResultControler resultControler = new ResultControler(controler);
            ResultWindow resultView = resultControler.getView();
            resultView.setInfo("Znalezione trasy " + start.getName()+" - "+end.getName() + ": ");
            resultView.setBounds(150, 100, resultView.getWidth(), resultView.getHeight());
            resultControler.setTableModel(tableModel);
            int resCount = tableModel.getRowCount();
            controler.setResultControler(resultControler);
            if(resCount==0){
                resultControler.blockDetailsBtn(false);
                JOptionPane.showMessageDialog(window, "Nie znaleziono żadnej trasy.");
            }else{
                resultControler.blockDetailsBtn(true);
                resultView.setVisible(true);
            }
             
        }

         private boolean isCheckedWeather() {
            return window.isCheckedWeather();
        }

        private boolean isCheckedRoad(){
            return window.isCheckedRoad();
        }

        private boolean isCheckedTraffic(){
            return window.isCheckedTraffic();
        }

       

    }

    private class StepByStepAction implements ActionListener{

        public void actionPerformed(ActionEvent e) {
            
            window.dispose();
            Node start = getSelectedStart();
            Node end = getSelectedEnd();
            boolean weatherCond = isCheckedWeather();
            boolean roadCond = isCheckedRoad();
            boolean trafficCond = isCheckedTraffic();
            int criteria = window.getSelectedItemIndex();
            if(start!=null && end!=null){
                if(start.equals(end)){
                    JOptionPane.showMessageDialog(window, "Punky początkowy i końcowy muszą być różne!");
                    return;
                }
                PrevNextControler prevNextControler = controler.getMainPanel().getPrevNextControler();
                prevNextControler.setStart(start);
                prevNextControler.setEnd(end);
                prevNextControler.setWeatherCond(weatherCond);
                prevNextControler.setRoadCond(roadCond);
                prevNextControler.setTrafficCond(trafficCond);
                prevNextControler.setCriterium(criteria);
                controler.getMainPanel().setPrevNextPanelVisible(true);
            }
        }

        private boolean isCheckedWeather() {
            return window.isCheckedWeather();
        }

        private boolean isCheckedRoad(){
            return window.isCheckedRoad();
        }

        private boolean isCheckedTraffic(){
            return window.isCheckedTraffic();
        }

    }



}
